package com.dcivision.lucene;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.impl.LogFactoryImpl;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;

import com.dcivision.dms.bean.DmsContent;
import com.dcivision.dms.bean.DmsDocument;
import com.dcivision.dms.bean.DmsDocumentDetail;
import com.dcivision.dms.bean.DmsLocMaster;
import com.dcivision.dms.bean.DmsRoot;
import com.dcivision.dms.bean.DmsVersion;
import com.dcivision.dms.dao.DmsContentDAObject;
import com.dcivision.dms.dao.DmsDocumentDAObject;
import com.dcivision.dms.dao.DmsDocumentDetailDAObject;
import com.dcivision.dms.dao.DmsLocMasterDAObject;
import com.dcivision.dms.dao.DmsRootDAObject;
import com.dcivision.dms.dao.DmsVersionDAObject;
import com.dcivision.framework.ApplicationException;
import com.dcivision.framework.ErrorConstant;
import com.dcivision.framework.GlobalConstant;
import com.dcivision.framework.SessionContainer;
import com.dcivision.framework.SystemParameterConstant;
import com.dcivision.framework.SystemParameterFactory;
import com.dcivision.framework.Utility;
import com.dcivision.framework.bean.SysUserDefinedIndexDetail;
import com.dcivision.framework.dao.SysUserDefinedIndexDetailDAObject;

/**
 * An class load information from database or package object to what we need.
 * @author Administrator
 */
class IndexOperation {

  private Log log = new LogFactoryImpl().getInstance(this.getClass());

  private Connection conn = null;

  private SessionContainer sessionContainer = null;

  private DmsDocumentDAObject dmsDocumentDAO = null;

  private DmsVersionDAObject dmsVersionDAO = null;

  private DmsContentDAObject dmsContentDAO = null;

  private DmsDocumentDetailDAObject dmsDocumentDetailDAO = null;

  private DmsLocMasterDAObject dmsLocMasterDAO = null;

  private DmsRootDAObject dmsRootDAO = null;

  private SysUserDefinedIndexDetailDAObject sysUseDefIndexDetailDAO = null;

  public IndexOperation(SessionContainer sessionContainer, Connection conn) {
    this.conn = conn;
    this.sessionContainer = sessionContainer;
  }

  /**
   * Get <code>Document</code> object from database.
   * @param dmsDocumentId
   * @return
   * @throws Exception
   */
  Document getDocument(Integer dmsDocumentId) throws ApplicationException {
    Document document = null;
    try {
      DmsDocument dmsDocument = (DmsDocument)this.getDmsDocumentDAO().getDocumentByID(dmsDocumentId, GlobalConstant.RECORD_STATUS_ACTIVE);
      if (dmsDocument!=null) {
        DmsVersion dmsVersion = (DmsVersion)this.getDmsVersionDAO().getTopVersionByDocumentID(dmsDocumentId);
        DmsContent dmsContent = (DmsContent)this.getDmsContentDAO().getObjectByID(dmsVersion.getContentID());
        List documentDetailList = this.getDmsDocumentDetailDAO().getListByDocumentID(dmsDocumentId);
        document = this.getDocumentByFullParam(dmsDocument, dmsContent, null, documentDetailList, null);
      }else {
        log.info("Document(DOC_ID="+dmsDocumentId+") was not found.");
      }
      return document;
    } catch (Exception ex) {
      log.info("Document(DOC_ID="+dmsDocumentId+") was not found. cause by exception:"+ex.toString());
      throw new ApplicationException(ErrorConstant.INDEX_CANNOT_GET_DATA_FROM_DB, ex, ex.toString());
    }
  }

  /**
   * Get <code>Document</code> object from database.
   * @param dmsDocument
   * @return
   * @throws Exception
   */
  Document getDocument(DmsDocument dmsDocument) throws ApplicationException {
    Document document = null;
    try {
      DmsVersion dmsVersion = (DmsVersion)this.getDmsVersionDAO().getTopVersionByDocumentID(dmsDocument.getID());
      DmsContent dmsContent = (DmsContent)this.getDmsContentDAO().getObjectByID(dmsVersion.getContentID());
      List documentDetailList = this.getDmsDocumentDetailDAO().getListByDocumentID(dmsDocument.getID());
      document = this.getDocumentByFullParam(dmsDocument, dmsContent, null, documentDetailList, null);
      return document;
    } catch (Exception ex) {
      log.warn("Document(DOC_ID="+dmsDocument.getID()+") was not found. cause by exception:"+ex.toString());
      throw new ApplicationException(ErrorConstant.INDEX_CANNOT_GET_DATA_FROM_DB, ex, ex.toString());
    }
  }

  /**
   * Get <code>Document</code> object from database.
   * @param dmsDocument
   * @param dmsContent
   * @param data
   * @param documentDetailList
   * @return
   * @throws ApplicationException
   */
  Document getDocument(DmsDocument dmsDocument, DmsContent dmsContent, InputStream data, List documentDetailList) throws ApplicationException {
    try {
      return this.getDocumentByFullParam(dmsDocument, dmsContent, data, documentDetailList, null);
    } catch (Exception ex) {
      log.warn("Document(DOC_ID="+dmsDocument.getID()+") was not found. cause by exception:"+ex.toString());
      throw new ApplicationException(ErrorConstant.INDEX_CANNOT_GET_DATA_FROM_DB, ex, ex.toString());
    }
  }

  /**
   * Get <code>Document</code> object from database.
   * @param dmsDocument
   * @param dmsContent
   * @param data
   * @param documentDetailList
   * @param basePath
   * @return
   * @throws ApplicationException
   */
  Document getDocument(DmsDocument dmsDocument, DmsContent dmsContent, InputStream data, List documentDetailList, String basePath) throws ApplicationException {
    try {
      return this.getDocumentByFullParam(dmsDocument, dmsContent, data, documentDetailList, basePath);
    } catch (Exception ex) {
      log.warn("Document(DOC_ID="+dmsDocument.getID()+") was not found. cause by exception:"+ex.toString());
      throw new ApplicationException(ErrorConstant.INDEX_CANNOT_GET_DATA_FROM_DB, ex, ex.toString());
    }
  }

  /**
   * Get <code>Document</code> object list from database.
   * @param dmsDocumentIds
   * @return
   * @throws Exception
   */
  List getDocuments(List dmsDocumentIds) throws ApplicationException {
    List documents = new ArrayList();
    try {
      Map basePathCache = new HashMap();

      List dmsDocuments = this.getDmsDocumentDAO().getListByIDList(dmsDocumentIds);
      for (int i=0; (dmsDocuments!=null && i<dmsDocuments.size()); i++) {
        DmsDocument dmsDocument = (DmsDocument)dmsDocuments.get(i);
        DmsVersion dmsVersion = (DmsVersion)this.getDmsVersionDAO().getTopVersionByDocumentID(dmsDocument.getID());
        DmsContent dmsContent = (DmsContent)this.getDmsContentDAO().getObjectByID(dmsVersion.getContentID());

        String basePath = null;
        if (basePathCache.containsKey(dmsDocument.getRootID())) {
          basePath = (String)basePathCache.get(dmsDocument.getRootID());
        }else {
          basePath = ((DmsLocMaster) this.getDmsLocMasterDAO().getObjectByID(((DmsRoot)getDmsRootDAO().getObjectByID(dmsDocument.getRootID())).getLocID())).getLocPath();
          basePathCache.put(dmsDocument.getRootID(), basePath);
        }
        List dmsDocumentDetailList = this.getDmsDocumentDetailDAO().getListByDocumentID(dmsDocument.getID());
        documents.add(this.getDocument(dmsDocument, dmsContent, null, dmsDocumentDetailList, basePath));
      }
      return documents;
    } catch (Exception ex) {
      log.warn("Document was not found. cause by exception:"+ex.toString());
      throw new ApplicationException(ErrorConstant.INDEX_CANNOT_GET_DATA_FROM_DB, ex, ex.toString());
    }
  }

  /**
   * Reset document field value by gived field names and vlaues
   * @param document
   * @param fieldNames
   * @param fieldValues
   * @return
   * @throws Exception
   */
  Document resetDocument(Document document, String[] fieldNames, String[] fieldValues) throws Exception {
    for (int i=0; i<fieldNames.length; i++) {
      document.removeFields(fieldNames[i]);
      if (!Utility.isEmpty(fieldValues[i]))
        document.add(getField(fieldNames[i], fieldValues[i]));
    }
    return document;
  }


  /**
   * Reset document statndard field value by gived new value.
   * @param document
   * @param dmsDocument
   * @param extension
   * @return
   * @throws Exception
   */
  Document resetDocumentStandardFields(Document document, DmsDocument dmsDocument, String extension) throws Exception {
    document.removeField(FieldNames.UID);
    document.removeField(FieldNames.DOCUMENT_NAME_SORT);
    document.removeField(FieldNames.DOCUMENT_NAME);
    document.removeField(FieldNames.ROOT_ID);
    document.removeField(FieldNames.REFERENCE_NO);
    document.removeField(FieldNames.DESCRIPTION);
    document.removeField(FieldNames.ITEM_STATUS);
    document.removeField(FieldNames.ITEM_SIZE);
    document.removeField(FieldNames.UPDATER_ID);
    document.removeField(FieldNames.UPDATE_DATE);
    document.removeField(FieldNames.EXTENSION);

    document.add(getField(FieldNames.UID, dmsDocument.getID().toString()));
    document.add(getField(FieldNames.DOCUMENT_NAME_SORT, dmsDocument.getDocumentName()));
    document.add(getField(FieldNames.DOCUMENT_NAME, dmsDocument.getDocumentName()));
    document.add(getField(FieldNames.ROOT_ID, dmsDocument.getRootID().toString()));
    if (!Utility.isEmpty(dmsDocument.getReferenceNo())) {
      document.add(getField(FieldNames.REFERENCE_NO, dmsDocument.getReferenceNo()));
    }
    if (!Utility.isEmpty(dmsDocument.getDescription())) {
      document.add(getField(FieldNames.DESCRIPTION, dmsDocument.getDescription()));
    }
    if (!Utility.isEmpty(dmsDocument.getItemStatus())) {
      document.add(getField(FieldNames.ITEM_STATUS, dmsDocument.getItemStatus()));
    }
    if (!Utility.isEmpty(dmsDocument.getItemSize())) {
      document.add(getField(FieldNames.ITEM_SIZE, dmsDocument.getItemSize().toString()));
    }
    if (!Utility.isEmpty(dmsDocument.getUpdaterID())) {
      document.add(getField(FieldNames.UPDATER_ID, dmsDocument.getUpdaterID().toString()));
    }
    if (!Utility.isEmpty(dmsDocument.getUpdateDate())) {
      document.add(getField(FieldNames.UPDATE_DATE, Utility.getCurrentTimestamp().toString()));
    }
    if (!Utility.isEmpty(extension)) {
      document.add(getField(FieldNames.EXTENSION, extension));
    }
    return document;
  }

  /**
   * Reset document default defined index field value.
   * @param document
   * @param dmsDocument
   * @return
   * @throws Exception
   */
  Document resetDocumentDDFIndexFields(Document document, DmsDocument dmsDocument) throws Exception {
    int defaultIndexSize = this.getDefaultIndexSize();
    // remove and add fields
    for (int i=0; i<defaultIndexSize; i++) {
      document.removeField(FieldNames.DEFAULT_INDEXES+i);
      Method getFieldValue = dmsDocument.getClass().getMethod("get"+FieldNames.DEFAULT_INDEXES_DB_PREFIX+(i+1), null);
      String indexValue = (String)getFieldValue.invoke(dmsDocument, null);
      if (!Utility.isEmpty(indexValue)) {
        document.add(getField(FieldNames.DEFAULT_INDEXES+i, FieldNames.DEFAULT_INDEXES, indexValue));
      }
    }
    return document;
  }

  /**
   * Reset document user defiened index field value.
   * @param document
   * @param documentDetailList
   * @return
   * @throws Exception
   */
  Document resetDocumentUDFIndexFields(Document document, List documentDetailList) throws Exception {
    int userDefinedIndexSize = this.getUserDefinedIndexSize();
    // remove and add fields
    for (int i=0; i<userDefinedIndexSize; i++) {
      document.removeField(FieldNames.USER_DEFINED_INDEXES+i);
    }
    document.removeField(FieldNames.USER_DEFINED_INDEX_ID);
    document.removeField(FieldNames.USER_DEFINED_INDEX_DETAIL_IDS);
    // add new fields
    if (documentDetailList!=null && !documentDetailList.isEmpty()) {
      List details = this.sortDocumentDetailList(documentDetailList);
      String udfIndexDetailIds = "";
      for (int i=0; i<details.size(); i++) {
        DmsDocumentDetail detail = (DmsDocumentDetail)details.get(i);
        if (i==0) {
          document.add(getField(FieldNames.USER_DEFINED_INDEX_ID, detail.getUserDefinedFieldID().toString()));
        }
        udfIndexDetailIds += ((i==0?"" : " ")+detail.getUserDefinedFieldDetailID());
        String value = (detail.getFieldValue()!=null ? detail.getFieldValue() : (detail.getDateValue()!=null ? detail.getDateValue().toString() : (detail.getNumericValue()!=null ? detail.getNumericValue().toString():null)));
        if (!Utility.isEmpty(value)) {
          document.add(getField(FieldNames.USER_DEFINED_INDEXES+i, FieldNames.USER_DEFINED_INDEXES, value));
        }
      }
      document.add(getField(FieldNames.USER_DEFINED_INDEX_DETAIL_IDS, udfIndexDetailIds));
    }
    return document;
  }

  /**
   * Get user deifned field setting name from database.
   * @param indexDetailID
   * @return
   * @throws Exception
   */
  public String getFieldLabel(Integer indexDetailID) throws Exception {
    return ((SysUserDefinedIndexDetail)getSysUserDefinedIndexDetailDAO().getObjectByID(indexDetailID)).getFieldName();
  }

  public Field getField(String fieldName, String fieldValue) throws Exception {
    return new Field(fieldName, fieldValue, FieldTypes.getStore(fieldName), FieldTypes.getIndex(fieldName), FieldTypes.getTermVector(fieldName));
  }

  public Field getField(String fieldName, String typeName, String fieldValue) throws Exception {
    return new Field(fieldName, fieldValue, FieldTypes.getStore(typeName), FieldTypes.getIndex(typeName), FieldTypes.getTermVector(typeName));
  }

  public int getDefaultIndexSize() {
    String defaultIndexSize =SystemParameterFactory.getSystemParameter(SystemParameterConstant.DMS_DEFAULT_PROFILE_FIELD_COUNT);
    return (defaultIndexSize==null ? 10 : Integer.parseInt(defaultIndexSize));
  }

  public int getUserDefinedIndexSize() {
    String userDefinedIndexSize =SystemParameterFactory.getSystemParameter(SystemParameterConstant.DMS_MAX_INDEX_FIELDS);
    return (userDefinedIndexSize==null ? 15 : Integer.parseInt(userDefinedIndexSize));
  }

  public List sortDocumentDetailList(List documentDetailList) throws ApplicationException {
    if (documentDetailList != null) {
      DmsDocumentDetail[] docDetailArray = (DmsDocumentDetail[]) documentDetailList.toArray(new DmsDocumentDetail[0]);

      boolean doMore = true;
      while (doMore) {
        doMore = false;
        for (int i = 0; i < docDetailArray.length - 1; i++) {
          if (docDetailArray[i].getUserDefinedFieldDetailID().intValue() > docDetailArray[i + 1].getUserDefinedFieldDetailID().intValue()) {
            DmsDocumentDetail tmpDocDetail = docDetailArray[i];
            docDetailArray[i] = docDetailArray[i + 1];
            docDetailArray[i + 1] = tmpDocDetail;
            doMore = true;
          } //end if
        } //end for
      } //end while

      return Utility.getList(docDetailArray);
    } else {
      return documentDetailList;
    }
  }

  /**
   * Get <code>Document</code> object with gived bean object.
   * @param basePath
   * @param dmsDocument
   * @param dmsContent
   * @param dmsDocumentDetailList
   * @return
   * @throws Exception
   */
  private Document getDocumentByFullParam(DmsDocument dmsDocument, DmsContent dmsContent, InputStream data, List dmsDocumentDetailList, String basePath) throws Exception {
    /*
    if (dmsDocument==null || dmsContent==null) {
      log.warn("DmsDocument or DmsContent can not be null.");
      return null;
    }
    */

    Document document = new Document();
    // set index main information
    document.add(getField(FieldNames.UID, dmsDocument.getID().toString()));
    document.add(getField(FieldNames.DOCUMENT_NAME_SORT, dmsDocument.getDocumentName()));
    document.add(getField(FieldNames.DOCUMENT_NAME, dmsDocument.getDocumentName()));
    document.add(getField(FieldNames.DOCUMENT_TYPE, dmsDocument.getDocumentType()));//Add a field. EIP-1296 lee 07/01/18

//  Add a field. EIP-1129  Jim Zhou   2007/05/22
    if (!Utility.isEmpty(dmsDocument.getEffectiveStartDate())){
      document.add(getField(FieldNames.EFFECTIVE_START_DATE, dmsDocument.getEffectiveStartDate().toString()));
    }

//  Add a field. EIP-1129  Jim Zhou   2007/05/22
    if (!Utility.isEmpty(dmsDocument.getEffectiveEndDate())){
      document.add(getField(FieldNames.EFFECTIVE_END_DATE, dmsDocument.getEffectiveEndDate().toString()));
    }

    document.add(getField(FieldNames.ROOT_ID, dmsDocument.getRootID().toString()));
    document.add(getField(FieldNames.RECORD_STATUS, GlobalConstant.RECORD_STATUS_ACTIVE));

    if (!Utility.isEmpty(dmsDocument.getReferenceNo())) {
      document.add(getField(FieldNames.REFERENCE_NO, dmsDocument.getReferenceNo()));
    }
    if (!Utility.isEmpty(dmsDocument.getDescription())) {
      document.add(getField(FieldNames.DESCRIPTION, dmsDocument.getDescription()));
    }
    if (dmsContent!=null && !Utility.isEmpty(dmsContent.getExt())) {
      document.add(getField(FieldNames.EXTENSION, dmsContent.getExt()));
    }
    if (!Utility.isEmpty(dmsDocument.getItemSize())) {
      document.add(getField(FieldNames.ITEM_SIZE, dmsDocument.getItemSize().toString()));
    }
    if (!Utility.isEmpty(dmsDocument.getItemStatus())) {
      document.add(getField(FieldNames.ITEM_STATUS, dmsDocument.getItemStatus()));
    }
    if (!Utility.isEmpty(dmsDocument.getUpdaterID())) {
      document.add(getField(FieldNames.UPDATER_ID, dmsDocument.getUpdaterID().toString()));
    }
    if (!Utility.isEmpty(dmsDocument.getUpdateDate())) {
      document.add(getField(FieldNames.UPDATE_DATE, dmsDocument.getUpdateDate().toString()));
    }

    int defaultIndexSize = this.getDefaultIndexSize();
    // remove and add fields
    for (int i=0; i<defaultIndexSize; i++) {
      Method getFieldValue = dmsDocument.getClass().getMethod("get"+FieldNames.DEFAULT_INDEXES_DB_PREFIX+(i+1), null);
      String indexValue = (String)getFieldValue.invoke(dmsDocument, null);
      if (!Utility.isEmpty(indexValue)) {
        document.add(getField(FieldNames.DEFAULT_INDEXES+i, FieldNames.DEFAULT_INDEXES, indexValue));
      }
    }

    //set physicalfile information
    String extension = dmsContent!=null ? dmsContent.getExt() : null;
    if (data!=null) {
      try {
        String content = null;
        if (dmsDocument.getScanDocumentForFullText()) {
          content = IndexConverter.getText(data, "TXT");
        }else {
          if (!IndexConverter.isForbidden(extension) && !Utility.isEmpty(extension)) {
            content = IndexConverter.getText(data, extension);
          }
        }
        if (content!=null)  document.add(getField(FieldNames.CONTENT, content));
      }catch (Exception ex) {
        log.warn("Document "+dmsDocument.getDocumentName()+"("+dmsDocument.getID()+") convert to text failure.");
      }finally {
        //try {data.close();} catch(Exception ignore) {}finally {data=null;}
      }
    }else if (!Utility.isEmpty(extension) && !IndexConverter.isForbidden(extension) && this.isDocumentType(dmsDocument)) {
      try {
        Integer segmentNo = dmsContent.getSegmentNO();
        if (basePath==null) basePath = this.getBasePath(dmsDocument.getRootID());
        File file = new File(basePath+"/"+(segmentNo!=null ? "Document/segment"+segmentNo.toString()+"/" : "")+dmsContent.getConvertedName());
        if (file.exists()) {
          InputStream ins = null;
          try {
            ins = new FileInputStream(file);
            String content = IndexConverter.getText(ins, extension);
            if (content!=null) document.add(getField(FieldNames.CONTENT, content));
          }catch (Exception ex) {
            log.warn("Document "+dmsDocument.getDocumentName()+"("+dmsDocument.getID()+") convert to text failure.");
          }finally {
            try {ins.close();} catch(Exception ignore) {}finally {ins=null;}
          }
        }else {
          log.warn("Document "+dmsDocument.getDocumentName()+"("+dmsDocument.getID()+") physical file is missing.");
        }
      }catch (Exception ex) {
        log.error(ex, ex);
      }
    }

    //set user defined profile
    if (dmsDocumentDetailList!=null && !dmsDocumentDetailList.isEmpty()) {
      List details = this.sortDocumentDetailList(dmsDocumentDetailList);
      String udfIndexDetailIds = "";
      for (int i=0; i<details.size(); i++) {
        DmsDocumentDetail detail = (DmsDocumentDetail)details.get(i);
        if (i==0) {
          document.add(getField(FieldNames.USER_DEFINED_INDEX_ID, detail.getUserDefinedFieldID().toString()));
        }
        udfIndexDetailIds += ((i==0?"" : " ")+detail.getUserDefinedFieldDetailID());
        String value = (detail.getFieldValue()!=null ? detail.getFieldValue() : (detail.getDateValue()!=null ? detail.getDateValue().toString() : (detail.getNumericValue()!=null ? detail.getNumericValue().toString():null)));
        if (!Utility.isEmpty(value)) {
          document.add(getField(FieldNames.USER_DEFINED_INDEXES+i, FieldNames.USER_DEFINED_INDEXES, value));
        }
      }
      document.add(getField(FieldNames.USER_DEFINED_INDEX_DETAIL_IDS, udfIndexDetailIds));
    }
    return document;
  }

  private boolean isDocumentType(DmsDocument dmsDocument) throws Exception {
    return (DmsDocument.DOCUMENT_TYPE.equals(dmsDocument.getDocumentType()) || DmsDocument.COMPOUND_DOC_TYPE.equals(dmsDocument.getDocumentType()) || DmsDocument.EMAIL_DOC_TYPE.equals(dmsDocument.getDocumentType()));
  }

  private String getBasePath(Integer rootID) throws Exception {
    return ((DmsLocMaster) this.getDmsLocMasterDAO().getObjectByID(((DmsRoot)getDmsRootDAO().getObjectByID(rootID)).getLocID())).getLocPath();
  }

  private DmsDocumentDAObject getDmsDocumentDAO() {
    if (this.dmsDocumentDAO==null) {
      this.dmsDocumentDAO = new DmsDocumentDAObject(this.sessionContainer, this.conn);
    }
    return this.dmsDocumentDAO;
  }

  private DmsVersionDAObject getDmsVersionDAO() {
    if (this.dmsVersionDAO==null) {
      this.dmsVersionDAO = new DmsVersionDAObject(this.sessionContainer, this.conn);
    }
    return this.dmsVersionDAO;
  }

  private DmsContentDAObject getDmsContentDAO() {
    if (this.dmsContentDAO==null) {
      this.dmsContentDAO = new DmsContentDAObject(this.sessionContainer, this.conn);
    }
    return this.dmsContentDAO;
  }

  private DmsDocumentDetailDAObject getDmsDocumentDetailDAO() {
    if (this.dmsDocumentDetailDAO==null) {
      this.dmsDocumentDetailDAO = new DmsDocumentDetailDAObject(this.sessionContainer, this.conn);
    }
    return this.dmsDocumentDetailDAO;
  }

  private DmsLocMasterDAObject getDmsLocMasterDAO() {
    if (this.dmsLocMasterDAO==null) {
      this.dmsLocMasterDAO = new DmsLocMasterDAObject(this.sessionContainer, this.conn);
    }
    return this.dmsLocMasterDAO;
  }

  private DmsRootDAObject getDmsRootDAO() {
    if (this.dmsRootDAO==null) {
      this.dmsRootDAO = new DmsRootDAObject(this.sessionContainer, this.conn);
    }
    return this.dmsRootDAO;
  }

  private SysUserDefinedIndexDetailDAObject getSysUserDefinedIndexDetailDAO() {
    if (this.sysUseDefIndexDetailDAO==null) {
      this.sysUseDefIndexDetailDAO = new SysUserDefinedIndexDetailDAObject(this.sessionContainer, this.conn);
    }
    return this.sysUseDefIndexDetailDAO;
  }

}
